/*
 * Copyright (c) Huawei Technologies Co., Ltd. 2019-2023. All rights reserved.
 * File Name     : vroce_cfg_common.h
 * Description   : common infos for kernel module and user module
 * History       : create file & add functions
 * 1.Date        : 2022-7-13
 * Author        : HW
 * Modification  : Created file
 */

#ifndef VROCE_CFG_COMMON_H
#define VROCE_CFG_COMMON_H

#include <linux/kthread.h>
#include <linux/uaccess.h>
#include <linux/hardirq.h> /* in_interrupt */
#include <linux/uuid.h>
#include "vroce_cfg_base.h"
struct vroce_cfg_data_hdr {
    unsigned int ops_type;
    unsigned short attr_type;
    unsigned int data_len;
    int ret_code;   // 0 : ok , others : error
};

struct vroce_cfg_racl_item {
    unsigned int racl_id;
    uuid_t racl_uuid;
    unsigned int ip_pair_num;
};

struct vroce_cfg_racl_info {
    unsigned int count;
    struct vroce_cfg_racl_item item[RACL_GROUP_MSG_MAX];
};

struct vroce_cfg_racl_ip_pair {
    unsigned int vip[IP_LEN];
    unsigned int vni;
    unsigned int vtep_ip[IP_LEN];
    unsigned int vf_id;
    unsigned int mode;
    unsigned char gw_mac[ETH_ADDR_LEN];
    unsigned char vm_mac[ETH_ADDR_LEN];
    unsigned char ip_type; /* bit[0]: 0/1 (vip v4/v6);   bit[1]: 0/1 (vtep_ip v4/v6); */
    unsigned char rsvd[3];
};

struct vroce_cfg_racl_ip_info {
    unsigned int racl_id;
    uuid_t racl_uuid;
    unsigned int ip_pair_num;
    struct vroce_cfg_racl_ip_pair pairs[RACL_IPPAIR_MSG_MAX];
};

struct arp_ip_mac {
    unsigned int ip;
    unsigned char mac[ETH_ADDR_LEN];
};

struct vroce_cfg_update_gwmac_msg {
    unsigned int racl_id;
    struct vroce_cfg_racl_ip_pair pair;
};

struct vroce_cfg_racl_arg_info {
    uuid_t racl_uuid;
    unsigned int vip[IP_LEN];
    unsigned char set_flags;
    unsigned char vip_type; /* bit[0]:0/1 v4/v6 */
    unsigned char rsvd[2];
    char filename[FILE_VROCE_LEN];
};

struct vroce_cfg_racl_args {
    struct vroce_cfg_racl_arg_info arg_info;
    struct vroce_cfg_racl_ip_info ip_info;
};
struct vroce_cfg_racl_ip_count {
    unsigned int total_count;
};

struct vroce_cfg_racl_dump_state {
    unsigned int start_index;
    unsigned int max_count;
};

struct vroce_cfg_racl_dump_ip_pair {
    unsigned int index;
    unsigned int racl_id;
    uuid_t racl_uuid;
    unsigned int vip[IP_LEN];
    unsigned int vni;
    unsigned int vtep_ip[IP_LEN];
    unsigned int vf_id;
    unsigned int mode;
    unsigned char gw_mac[ETH_ADDR_LEN];
    unsigned char vm_mac[ETH_ADDR_LEN];
    unsigned char ip_type; /* bit[0]: 0/1 (vip v4/v6);   bit[1]: 0/1 (vtep_ip v4/v6); */
    unsigned char rsvd[3];
};

enum dscp_type {
    VROCE_CFG_DSCP_RC,
    VROCE_CFG_DSCP_UD,
    VROCE_CFG_DSCP_XRC,
    VROCE_CFG_DSCP_TYPE_MAX
};

enum qos_precision {
    VROCE_CFG_PRECISION_LOW,
    VROCE_CFG_PRECISION_HIGH,
    VROCE_CFG_PRECISION_MAX
};
struct vroce_ctx_gpa_info_entry {
    unsigned short func_id;
    unsigned short rsvd;

    unsigned int mode;
    unsigned int gpa_addr0_hi;
    unsigned int gpa_addr0_lo;
    unsigned int gpa_len0;
}; /* the same struct defined in vroce_mpu.h, modify them together */

struct vroce_pci_hole_info_entry {
    unsigned int entry_idx;

    /* pcie hole 32-bit region */
    unsigned int gpa_addr0_hi;
    unsigned int gpa_addr0_lo;
    unsigned int gpa_len0_hi;
    unsigned int gpa_len0_lo;

    /* pcie hole 64-bit region */
    unsigned int gpa_addr1_hi;
    unsigned int gpa_addr1_lo;
    unsigned int gpa_len1_hi;
    unsigned int gpa_len1_lo;

    unsigned int domain_id;
    u32 rsvd    : 21;
    u32 vf_nums : 11;
    unsigned int vroce_vf_bitmap;
}; /* the same struct defined in vroce_mpu.h, modify them together */

struct vroce_funcfg_info_entry {
    unsigned short func_id;
    unsigned short rsvd;

    unsigned int entry_vld : 1;
    unsigned int entry_idx : 5;
    unsigned int rsvd1 : 26;
}; /* the same struct defined in vroce_mpu.h, modify them together */

struct vroce_cfg_vf_info_entry {
    unsigned int racl_id;
    unsigned int vtep_ip;
    unsigned short func_id;
    unsigned short ctrl_func_id;
    unsigned short vlan_id : 12;
    unsigned short bond_id : 4;
    unsigned char vtep_mac[ETH_ADDR_LEN];
    unsigned char dscp_ud;
    unsigned char dscp_rc;
    unsigned char dscp_xrc;
    unsigned char cos_num_ud;
    unsigned char cos_num_rc;
    unsigned char cos_num_xrc;
    unsigned char group_ud;
    unsigned char group_rc;
    unsigned char group_xrc;
    unsigned char set_flags;
    unsigned char base_id;
    unsigned char host_id;
    unsigned char default_gwmac[ETH_ADDR_LEN];
    unsigned char rsvd[2];
    unsigned int vni    : 24;
    unsigned int vni_en : 8;
    unsigned int max_qp_num;
    unsigned int max_srq_num;
    unsigned int vtep_ipv6[IP_LEN];
}; /* the same struct defined in vroce_mpu.h, modify them together */

struct vroce_cfg_vf_info_list_entry_comm {
    unsigned int vtep_ip;
    unsigned int vtep_ipv6[IP_LEN];
    unsigned char vtep_mac[ETH_ADDR_LEN];
    unsigned char default_gwmac[ETH_ADDR_LEN];
    unsigned char dscp_ud;
    unsigned char dscp_rc;
    unsigned char dscp_xrc;
    unsigned char cos_num_ud;
    unsigned char cos_num_rc;
    unsigned char cos_num_xrc;
    unsigned char group_ud;
    unsigned char group_rc;
    unsigned char group_xrc;
    unsigned char rsvd[3];
}; /* the same struct defined in vroce_mpu.h, modify them together */

struct vroce_cfg_vf_info_list_entry {
    unsigned int racl_id;
    unsigned short func_id;
    unsigned short ctrl_pf_func_id;
    unsigned short vlan_id     : 12;
    unsigned short bond_id     : 4;
    unsigned char set_flags;
    unsigned char base_id;
    unsigned char host_id;
    unsigned char rsvd[3];
    unsigned int vni    : 24;
    unsigned int vni_en : 8;
    unsigned int max_qp_num;
    unsigned int max_srq_num;
}; /* the same struct defined in vroce_mpu.h, modify them together */

struct vroce_cfg_vf_info {
    char vf_name[DEV_NAME_LEN];
    char bdf[BDF_STR_LEN];
    char rsvd0[3];
    uuid_t racl_uuid;
    unsigned char vm_mac[ETH_ADDR_LEN];
    char rsvd1[2];
    unsigned int vni;
    struct vroce_cfg_vf_info_entry info_entry;
};

struct vroce_cfg_feature_info {
    unsigned int master_feature;
    unsigned int slave_feature;
};

struct vroce_cfg_dscp_info {
    unsigned char group_id;
    unsigned char dscp;
    unsigned char cos_num;
    unsigned char type;
    unsigned char bw_proportion;
    unsigned char priority;
    unsigned char pfc;
    unsigned char precision;
    unsigned char set_flags;
    unsigned char rsvd[3];
};

struct vroce_cfg_dscp_type {
    unsigned char group_id;
    unsigned char dscp;
    unsigned char cos_num;
};

struct vroce_cfg_dscp_group {
    unsigned char set_flags;
    unsigned char bw_proportion;
    unsigned char priority;
    unsigned char pfc;
};

struct vroce_cfg_qos {
    unsigned char precision;
    struct vroce_cfg_dscp_group group[GROUP_ID_MAX];
};

struct vroce_cfg_global_info {
    unsigned short vlan_id;
    unsigned char precision;
    unsigned char set_flags;
};

struct vroce_cfg_icq_threshold_info {
    unsigned int icq_length_threshold;
};

typedef struct {
    uint8_t addr[ROCEMIG_IPV6_ADDR_LEN];
} roce_in6_addr_t;
 
struct roce_cfg_migentry_item {
    uint32_t vni;
    union {
        uint32_t ip4;
        roce_in6_addr_t ip6;
    } dvip;
    /* dvip: ipv4 bit0 is 0, ipv6 bit0 is 1
       vtep_ip: set ipv4 bit1 is 1, set ipv6 bit2 is 1 */
    uint8_t ip_flag;
    uint8_t resv[1];
    uint8_t nexthop_mac[ETH_ADDR_LEN];
    uint32_t vtep_ip4;
    roce_in6_addr_t vtep_ip6;
};
struct roce_cfg_dump_migentry_item {
    struct roce_cfg_migentry_item migentry;
    uint64_t hits;
};
 
 
#define DVIP_IPV4_FLAG 0xfe
#define DVIP_IPV6_FLAG 0xff
 
#define ROCEMIG_FLAG_DVIP_IPV6_MASK 0x01
#define ROCEMIG_DVIP_IS_IPV4(entry) (!((entry)->ip_flag & ROCEMIG_FLAG_DVIP_IPV6_MASK))
 
#define ROCEMIG_FLAG_VTEPIP_IPV4_MASK 0x02
#define ROCEMIG_VTEPIP_IPV4_IS_SET(entry) ((entry)->ip_flag & ROCEMIG_FLAG_VTEPIP_IPV4_MASK)
 
#define ROCEMIG_FLAG_VTEPIP_IPV6_MASK 0x04
#define ROCEMIG_VTEPIP_IPV6_IS_SET(entry) ((entry)->ip_flag & ROCEMIG_FLAG_VTEPIP_IPV6_MASK)
 
 
struct roce_cfg_dump_migentry_batch {
    int count;
    struct roce_cfg_dump_migentry_item migentry_batch[ROCEMIG_ENTRY_MAX_COUNT];
};

struct vroce_cmd_algo_para {
    unsigned int algo_type;
    unsigned int static_flag;
    unsigned int shadow_idx;
    unsigned int para_len;
    union {
        struct {
            unsigned int rsvd1 : 16;
            unsigned int wnd_rst_tmout : 8;
            unsigned int wnd_rst_ratio : 8;
        } bs;
        unsigned int value;
    } para;
    unsigned int rsvd[4]; /* reserve 16 Bytes */
};

struct vroce_cfg_cc_param_info {
    unsigned int comm_info_head[2]; /* head 8 Bytes */
    unsigned short func_id;
    unsigned short rsvd;
    struct vroce_cmd_algo_para data;
};

struct vroce_cfg_probe_filter {
    unsigned int dst_qpn;
    unsigned int sip[IP_LEN];
    unsigned int dip[IP_LEN];
    unsigned int sport;
    unsigned int opcode;
    unsigned int count;
    unsigned short func_id;
    unsigned short set_flags;
    unsigned char ip_type;
    unsigned char rsvd[3];
};

struct vroce_cfg_probe_info {
    char vf_name[DEV_NAME_LEN];
    struct vroce_cfg_probe_filter filter;
};

struct vroce_cap_block_num_attr {
    unsigned int block_num_idx;
    unsigned int shift;
    unsigned int num;
};

struct vroce_cap_info {
    unsigned int func_id;
    unsigned int poll_ci;
    unsigned int cap_mode;   /* 0: drop mode, 1: overwrite mode */
    unsigned int mode;       /* 0: func mode, 1: qp mode */
    unsigned int cap_status; /* 0: stopped, 1: running */
    unsigned int block_num_idx;
    unsigned int block_num_per_entry;
    unsigned int maxnum;
    unsigned long long que_addr[PROBE_PA_NUM][PROBE_ADDR_TYPE_NUM][PROBE_ADDR_NUM];
};

typedef struct roce_dfx_cap_cfg_tbl {
    unsigned int ci_index;

    union {
        struct {
            unsigned char cap_block_num_shift;
            unsigned char cap_mode;
            unsigned char qp_mode;
            unsigned char rsvd;
        } bs;
        unsigned int value;
    } dw1;

    union {
        struct {
            unsigned int state : 8;
            unsigned int rsvd : 8;
            unsigned int cap_func : 16;
        } bs;
        unsigned int value;
    } dw2;

    unsigned int maxnum;
} roce_dfx_cap_cfg_tbl_s;

struct vroce_cfg_vf_statics_entry {
    unsigned long long rx_cnt;
    unsigned long long rx_bytes;
    unsigned int rx_err;
    unsigned int rx_loss;
    unsigned int rx_ce;
    unsigned int rx_not_ready;
    unsigned long long tx_cnt;
    unsigned long long tx_bytes;
    unsigned int tx_timeout;
    unsigned int tx_roceacl_miss;
    unsigned int tx_vf_config_miss;
};

struct vroce_cfg_global_statistic_info {
    unsigned long long rx_pfc_pkts_port;
    unsigned long long rx_pri_pkts_port[PFC_NUM];
    unsigned long long tx_pfc_pkts_port;
    unsigned long long tx_pri_pkts_port[PFC_NUM];
    unsigned long long tx_bond_pkts_port0;
    unsigned long long tx_bond_pkts_port1;
    unsigned long long tx_bond_pkts_port2;
    unsigned long long tx_bond_pkts_port3;
    unsigned int tx_bond_pkts_mode_err;
    unsigned int tx_bond_pkts_port_err;
};

struct vroce_cfg_dev {
    char vf_name[DEV_NAME_LEN];
    unsigned short func_id;             /* global function index */
    unsigned short glb_pf_vf_offset;    /* vf offset */
    unsigned char func_type;            /* 0-PF 1-VF 2-PPF */
    unsigned char itf_idx;              /* pcie interface index */
    unsigned short max_vfs;             /* max vfs */
    unsigned int dbdf;                 /* pf dbdf */
    unsigned char base_id;
    unsigned int racl_id;
    unsigned int vtep_ip;
    unsigned int vtep_ipv6[IP_LEN];
    unsigned char default_gwmac[ETH_ADDR_LEN];
    unsigned char bond_slaves;
    unsigned char vm_mac[ETH_ADDR_LEN];
    unsigned int vni;
    struct hinic3_lld_dev *lld_dev;
};

// uP data define
struct vroce_up_msg_hdr {
    int up_ret;
    unsigned int entry_num;
};

struct vroce_dscp_flow_ctrl_info {
    unsigned char drop_en; /* 1: drop   0: not drop */
    unsigned char rsvd[3]; /* reserve 3 Bytes */
};

/* racl vip hash key (smf 20B) */
struct racl_key {
    u32 racl_id;
    u32 vip[IP_LEN];
};

/* racl vip hash value (smf 36B) */
struct racl_value {
    u32 vni;
    u32 vtep_ip[IP_LEN];
    u16 vf_id;
    u8 mode;
    u8 vtep_ip_type; /* bit[0]: 0/1 (vtep_ip v4/v6); */
    u8 gw_mac[ETH_ADDR_LEN];
    u8 vm_mac[ETH_ADDR_LEN];
};

/* vroce migrate forward hash key (smf 20B) */
struct mig_entry_key {
    u32 vni : 24;
    u32 dvip_flag : 8; // dvip: ipv4 bit0 is 0, ipv6 bit0 is 1
    union {
        u32 ip4;
        roce_in6_addr_t ip6;
    } dvip;
};
 
/* vroce migrate forward hash value (smf 40B) */
struct mig_entry_value {
    u64 hits;
    u32 vtep_ip4;
    roce_in6_addr_t vtep_ip6;
    u8 nexthop_mac[ETH_ADDR_LEN];
    // vtep ip: set ipv4 bit0 is 1, set ipv6 bit1 is 1
    u8 vtep_ip_flag;
    // ctr_id for hits
    u8 ctr_id;
    u8 rsvd[4];
};

struct vroce_neigh {
    u32 dst_ip[IP_LEN];
    int family;
    u8 dead;
    u8 mac[ETH_ADDR_LEN];
    char ifname[DEV_NAME_LEN];
};

enum {
    VRDMA_ERR = 0,
    VRDMA_WARNING,
    VRDMA_INFO,
    VRDMA_DEBUG,
    VRDMA_LOG_LEVEL_MAX
};

typedef struct {
    u16 func_id;
    u16 magic_num;

    u32 sq_vfbase_id;
    u32 stful_sq_txqid_range;

    u32 rdma_vfbase_id;
    u32 stful_rdma_txqid_range;
} vroce_func_allocated_flexq; /* the same struct defined in vroce_mpu.h, modify them together */

typedef struct {
    vroce_func_allocated_flexq info;
    struct list_head node;
} vroce_func_allocated_flexq_list;

__attribute__((unused)) static const char *g_level_names[VRDMA_LOG_LEVEL_MAX] = {
    "err",      // VRDMA_ERR
    "warning",  // VRDMA_WARNING
    "info",     // VRDMA_INFO,
    "debug"     // VRDMA_DEBUG,
};

__attribute__((unused)) static const char *g_kern_levels[VRDMA_LOG_LEVEL_MAX] = {
    KERN_ERR,      // VRDMA_ERR
    KERN_WARNING,  // VRDMA_WARNING
    KERN_INFO,     // VRDMA_INFO,
    KERN_DEBUG     // VRDMA_DEBUG,
};

int get_log_level(void);
void set_log_level(int log_level);

/**
 * dprint - Selective debug print for process, SoftIRQ or HardIRQ context
 *
 * Debug print with selectable debug categories,
 * starting with header
 * - "loglevel current->comm[current->pid] __func__[__LINE__]" for process context
 * - "loglevel current->comm[irq] __func__[__LINE__]" for IRQ context
 *
 * @loglevel  : log-level to print
 * @fmt     : printf compliant format string
 * @args    : printf compliant argument list
 */
#define dprint(level, fmt, args...)                  \
    do {                                             \
        if (level <= get_log_level()) {                \
            if (!in_interrupt()) (void)printk("%s%s %s[%5d] %s[%d]: " fmt, g_kern_levels[level], \
                g_level_names[level], current->comm, current->pid,  __func__, __LINE__, ##args); \
            else (void)printk("%s%s %s[irq] %s[%d]: " fmt, g_kern_levels[level], \
                g_level_names[level], current->comm, __func__, __LINE__, ##args); \
        }                                                 \
    } while (0)
#endif
